// 校验json格式是否于预设的一致 
// 对于preFixed中的每个key，target必须都有
// 支持的值包括:string,json,array
function Node(prefix, template, target) {
  this.prefix = prefix;
  this.template = template;
  this.target = target;
}

function Result(isOk, msg) {
  this.isOk = isOk;
  this.msg = msg;
}

function check(template, target) {
  var cmpList = [];
  var result;

  cmpList.push(new Node("", template, target));

  //
  while (cmpList.length > 0) {
    var aNode = cmpList.shift();
    var layerResult = layerValid(aNode, cmpList);
    if (!layerResult.isOk) {
      result = layerResult;
      break;
    }
  }

  if (!result) {
    result = new Result(true);
  }

  return result;
}

function layerValid(aNode, cmpList) {
  var prefix = aNode.prefix;
  var template = aNode.template;
  var target = aNode.target;
  // console.log("compare at " + prefix);

  if (Array.isArray(template) && Array.isArray(target)) {
    cmpJsonArr(prefix, template, target, cmpList);
    return new Result(true);
  }

  if (Array.isArray(template) !== Array.isArray(target)) {
    return new Result(false, prefix + " type unmatch");
  }

  if (typeof template !== typeof target) {
    return new Result(false, prefix + " type unmatch");
  }

  return cmpJsonObj(prefix, template, target, cmpList);

}

function cmpJsonArr(prefix, arrTemplate, arrTarget, cmpList) {
  // we select the first item to compare
  var node = new Node(prefix + "[", arrTemplate[0], arrTarget[0]);
  cmpList.push(node);
}

function cmpJsonObj(prefix, template, target, cmpList) {
  for (var key in template) {
    var nextPrefix = getNewPrefix(prefix, key);

    var vTarget = target[key];
    if (!vTarget) {
      return new Result(false, "no correspond key:" + nextPrefix);
    }

    //
    var vTemplate = template[key];
    if (typeof vTemplate !== typeof vTarget) {
      return new Result(false, "type unmatch at " + nextPrefix);
    }

    // regard same type
    if (typeof vTemplate !== "object") {
      continue;
    }

    // object
    if (Array.isArray(vTemplate) && Array.isArray(vTarget)) {
      console.log("json has a array item");
      cmpJsonArr(nextPrefix, vTemplate, vTarget, cmpList);
    } else {
      var node = new Node(nextPrefix, vTemplate, vTarget);
      cmpList.push(node);
    }

  }
  return new Result(true);
}


function getNewPrefix(pre, key) {
  return pre + "{" + key;
}

module.exports = {
  check: check
}